'''
Author: “Ren 778315181@qq.com
Date: 2022-09-08 15:36:10
LastEditors: “Ren 778315181@qq.com
LastEditTime: 2022-09-14 09:57:41
FilePath: \PKPD\Efficacy.py
Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
'''
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from multiprocessing import Pool
from scipy.optimize import curve_fit
from sklearn.metrics import r2_score
from utils.util import EMax
import tqdm
import datetime
import os


    

def bsAbs(target1_kon,target1_koff,target2_kon,target2_koff,abs,volumn = 2e-4,moa = 1.5e+4,moa_expression = 5e+5,tumor = 5e+4,tumor_expression = 1e+5):
    R = 6.023e+23 / 1e+9
    target1 = moa * moa_expression/R # nMol 
    target2 = tumor * tumor_expression/R # nMol 
    abs = abs * volumn
    # target1 = moa * moa_expression/R/volumn # nMol 
    # target2 = tumor * tumor_expression/R/volumn # nMol 
    # print('params',target1,target1,abs)
    abst1 = 0
    abst2 = 0
    trimer = 0
    interval = 0.001
    #
    metric = {}
    metric['times'] = [0]
    metric['abss'] = [abs]
    metric['target1s'] = [target1]
    metric['target2s'] = [target2]
    metric['abst1s'] = [0]
    metric['abst2s'] = [0]
    metric['trimer'] = [0]
    metric['TO1'] = [0]
    metric['TO2'] = [0]
    metric['DTO1'] = [0]
    metric['DTO2'] = [0]
    metric['TTO1'] = [0]
    metric['TTO2'] = [0]
    metric['MixTO'] = [0]
    metric['trimer/tumor'] = [0]
    metric['trimer/moa'] = [0]
    for i in np.arange(interval,72,interval): # 0到72小时变化
        # 计算梯度
        delta_abs = target1_koff *abst1 + target2_koff * abst2 - target1_kon * abs * target1/volumn - target2_kon * abs * target2/volumn
        delta_target1 = target1_koff * (abst1 + trimer)  - target1_kon * (abs+abst2) * target1/volumn
        delta_target2 = target2_koff *(abst2 + trimer)  - target2_kon * (abs+abst1) * target2/volumn
        delta_abst1 = - target1_koff *abst1 - target2_kon * abst1 *target2/volumn + target1_kon * abs * target1/volumn + target2_koff *trimer
        delta_abst2 = - target2_koff *abst2 - target1_kon * abst2 *target1/volumn + target2_kon * abs * target2/volumn + target1_koff *trimer
        delta_trimer = - target2_koff *trimer - target1_koff * trimer + target1_kon * abst2 *target1/volumn + target2_kon * abst1 *target2/volumn
        # 更新梯度
        abs += delta_abs * interval
        target1 += delta_target1 * interval
        target2 += delta_target2 * interval
        abst1 += delta_abst1 * interval
        abst2 += delta_abst2 * interval
        trimer += delta_trimer * interval
        if not (abs>=0 and target1>=0 and  target2>=0 and abst1>=0 and abst2>=0 and trimer>=0):
            break
        # 保存结果
        metric['abss'].append(abs)
        metric['target1s'].append(target1)
        metric['target2s'].append(target2)
        metric['abst1s'].append(abst1)
        metric['abst2s'].append(abst2)
        metric['trimer'].append(trimer/volumn)
        metric['times'].append(i)
        metric['TO1'].append((abst1+trimer)/metric['target1s'][0])
        metric['TO2'].append((abst2+trimer)/metric['target2s'][0])
        metric['DTO1'].append((abst1)/metric['target1s'][0])
        metric['DTO2'].append((abst2)/metric['target2s'][0])
        metric['TTO1'].append(trimer/metric['target1s'][0])
        metric['TTO2'].append(trimer/metric['target2s'][0])
        metric['trimer/tumor'].append(trimer*R/tumor)
        metric['trimer/moa'].append(trimer*R/moa)
        metric['MixTO'].append(trimer/metric['target2s'][0]*(abst1+trimer)/metric['target1s'][0])
    metric = pd.DataFrame.from_dict(metric)
    metric = metric.set_index('times')
    # metric.to_excel(save_result,index=None)
    return metric

def efficacy(x,e0,em,e50):
    return e0+em*(x)/(e50+x) # 增大梯度

def trimer_efficay(combinations,params):
    p = Pool(3)
    jobs = []
    for com in combinations:
        jobs.append(p.apply_async(bsAbs,args=(*com,)))
    p.close()
    p.join()
    trimer = []
    maxT = -1
    for i,job in enumerate(tqdm.tqdm(jobs)):
        metric = job.get(100)
        trimer.append(max(metric['trimer/moa']))
    y_pred = efficacy(np.array(trimer),*params)
    return y_pred

if __name__=='__main__':
    x = np.array([0,80,16,3.2])
    y = np.array([11.7,18.10,24.15,33.40])
    p = Pool(3)
    # fit
    data = pd.read_csv('../cleandata/cleandata.csv')
    combinations = []
    iloc = -1
    for abs in x:
        target1_kon = data.iloc[iloc]['ka (1/Ms)']/1e+9*3600 # /nMol*h
        target1_koff = data.iloc[iloc]['kdis (1/s)']*3600 # /h
        target2_kon = data.iloc[iloc]['ka2 (1/Ms)']/1e+9*3600 # /nMol*h
        target2_koff = data.iloc[iloc]['kdis2 (1/s)']*3600 # /h
        volumn = 2e-4
        combinations.append([target1_kon,target1_koff,target2_kon,target2_koff,abs,volumn])
    jobs = []
    for com in combinations:
        print('param',com)
        jobs.append(p.apply_async(bsAbs,args=(*com,)))
    p.close()
    p.join()
    trimer_ratio = []
    for i,job in enumerate(tqdm.tqdm(jobs)):
        metric = job.get(100)
        trimer_ratio.append(max(metric['trimer/moa']))
        print(max(metric['trimer/moa']))
    # efficacy_model = EMax()
    # efficacy_model.fit(trimer_ratio,y)
    # y_ = efficacy_model.predict(np.array(trimer_ratio))
    # print('Trimer R:',r2_score(y,y_))
    # efficacy_model.save('models/361_305.pkl')
    # efficacy_model.load('models/361_305.pkl')

    # x= [0]
    # for i in range(-3,3):
    #     x += list(np.arange(10**(i),10**(1+i),10**(i)))
    
    # combinations = []
    # for abs in x:
    #     combinations.append([target1_kon,target1_koff,target2_kon,target2_koff,abs,volumn])
    # y = trimer_efficay(combinations,params)

    # combinations = []
    # for abs in x:
    #     combinations.append([target1_kon,target1_koff,target2_kon,target2_koff,abs,volumn,1.5e+4,5e+5,1.5e+4,1e+5])
    # y_low = trimer_efficay(combinations,params)
    # combinations = []
    # for abs in x:
    #     combinations.append([target1_kon,target1_koff,target2_kon,target2_koff,abs,volumn,1.5e+4,5e+5,5e+5,1e+6])
    # y_up = trimer_efficay(np.array(combinations),params)
    # combinations = []
    # for abs in x:
    #     combinations.append([target1_kon,target1_koff,target2_kon,target2_koff,abs,volumn,1.5e+4,5e+5,1.5e+4,1e+4])
    # normal_low = trimer_efficay(np.array(combinations),params)
    # combinations = []
    # for abs in x:
    #     combinations.append([target1_kon,target1_koff,target2_kon,target2_koff,abs,volumn,1.5e+4,5e+5,5e+5,1e+4])
    # normal_high = trimer_efficay(np.array(combinations),params)
    # # plt.scatter(np.log(x),y)
    # plt.plot(np.log(x),y,color='b',label= 'tumor')
    # plt.plot(np.log(x),y_up,color='g',label= 'tumor-10:1')
    # plt.plot(np.log(x),y_low,color='c',label= 'tumor-1:1')
    # plt.plot(np.log(x),normal_low,color='y',label='normal-1:1')
    # plt.plot(np.log(x),normal_high,color='r',label='normal-10:1')
    # plt.fill_between(np.log(x),y_up,y_low,color='bisque')
    # plt.title('E:T')
    # plt.legend()
    # plt.show()


    
    # 305 combination
    # combinations = []
    # for abs in x:
    #     combinations.append([target1_kon,target1_koff,target2_kon,target2_koff,abs,volumn,1.5e+4,5e+5,5e+4,1e+4])
    # y_low = trimer_efficay(combinations,params)
    # combinations = []
    # for abs in x:
    #     combinations.append([target1_kon,target1_koff,target2_kon,target2_koff,abs,volumn,1.5e+4,5e+5,5e+4,1e+6])
    # y_up = trimer_efficay(np.array(combinations),params)
    # combinations = []
    # for abs in x:
    #     combinations.append([target1_kon,target1_koff,target2_kon,target2_koff,abs,volumn,1.5e+4,5e+3,5e+4,1e+4])
    # normal = trimer_efficay(np.array(combinations),params)
    # plt.scatter(np.log(x),y)
    # plt.plot(np.log(x),y,color='b',label= 'tumor-mean')
    # plt.plot(np.log(x),y_up,color='g',label= 'tumor-95')
    # plt.plot(np.log(x),y_low,color='c',label= 'tumor-1')
    # plt.scatter(np.log(x),normal,color='y',label='normal')
    # plt.fill_between(np.log(x),y_up,y_low,color='bisque')
    # plt.title('305')
    # plt.legend()
    # plt.show()

    # 361
    # combinations = []
    # for abs in x:
    #     combinations.append([target1_kon,target1_koff,target2_kon,target2_koff,abs,volumn,1.5e+4,1e+5,5e+4,1e+5])
    # y_low = trimer_efficay(combinations,params)
    # combinations = []
    # for abs in x:
    #     combinations.append([target1_kon,target1_koff,target2_kon,target2_koff,abs,volumn,1.5e+4,2e+6,5e+4,1e+5])
    # y_up = trimer_efficay(np.array(combinations),params)
    # combinations = []
    # for abs in x:
    #     combinations.append([target1_kon,target1_koff,target2_kon,target2_koff,abs,volumn,1.5e+4,5e+3,1.5e+6,1e+4])
    # normal = trimer_efficay(np.array(combinations),params)
    # plt.scatter(np.log(x),y)
    # plt.plot(np.log(x),y,color='b',label= 'mean')
    # plt.plot(np.log(x),y_up,color='g',label= 'm-95')
    # plt.plot(np.log(x),y_low,color='c',label= 'm-1')
    # plt.scatter(np.log(x),normal,color='y',label='normal')
    # plt.fill_between(np.log(x),y_up,y_low,color='bisque')
    # plt.title('361e')
    # plt.legend()
    # plt.show()
